﻿using System;
using System.Collections.Generic;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GzipManagerPro.IO.Helpers;

namespace GzipManagerPro.IO
{
    partial class Archive
    {
        private bool WriteHeader(System.IO.Stream stream)
        {
            try
            {
                OnArchiveMessage(new ArchiveMessageEventArgs(this.TotalProgress, this.CurrentProgress, "Writing header..."));
                byte[] data = this.SerializeToBinary()
                    .ToGzip();
                
                stream.Write(data, 0, data.Length);

                OnArchiveMessage(new ArchiveMessageEventArgs(this.TotalProgress, this.CurrentProgress, "Writing header length..."));
                data = BitConverter.GetBytes(data.Length);
                stream.Write(data, 0, data.Length);

                return true;
            }
            catch(Exception ex)
            {
                OnArchiveError(new ArchiveErrorEventArgs(ex));
                return false;
            }
        }

        

        
        public bool Save(System.IO.Stream stream)
        {
            try
            {
                CurrentProgress = 0;
                // Step 1: Calculating files count:
                OnArchiveMessage(new ArchiveMessageEventArgs(this.TotalProgress, this.CurrentProgress, "Calculating job..."));
                this.TotalProgress = this.RootFolder.GetFilesCount() + CalculateFilesProgressCount;
                this.CurrentProgress += CalculateFilesProgressCount;

                // adding header count
                this.TotalProgress += HeaderProgressCount;
                // Step 2: Write Files
                OnArchiveMessage(new ArchiveMessageEventArgs(this.TotalProgress, this.CurrentProgress, "Writing files..."));
                if (!this.RootFolder.WriteTo(stream, this))
                    return false;
                this.CurrentProgress += HeaderProgressCount;
                // Step 3: Write Header
                if (!this.WriteHeader(stream))
                    return false;

                return true;
            }
            catch (Exception ex)
            {
                OnArchiveError(new ArchiveErrorEventArgs(ex));
                return false;
            }
        }

        public bool SaveToFile()
        {
            try
            {
                OnArchiveMessage(new ArchiveMessageEventArgs(this.TotalProgress, this.CurrentProgress, "Starting create archive..."));
                System.IO.FileStream stream;
                stream = new System.IO.FileStream(this.FileName,
                    System.IO.File.Exists(this.FileName) ? System.IO.FileMode.Truncate : System.IO.FileMode.CreateNew,
                    System.IO.FileAccess.Write,
                    System.IO.FileShare.None);

                bool result = this.Save(stream);
                stream.Close();
                OnArchiveMessage(new ArchiveMessageEventArgs(this.TotalProgress, this.CurrentProgress, "Archive has been created successfully."));
                return result;
            }
            catch (Exception ex)
            {
                OnArchiveError(new ArchiveErrorEventArgs(ex));
                return false;
            }

        }
    }
}
